package com.softWang.file.util.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.softWang.file.mapper.FileManageMapper;
import com.softWang.file.po.FileManage;
import com.softWang.file.util.IFileSaveUtil;
import com.softWang.file.util.MimeTypeUtils;
import com.softWang.file.vo.fileManage.FileSaveResult;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.ResponseInputStream;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3ClientBuilder;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.services.s3.model.*;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URI;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Component("FileSaveUtilS3Impl")
public  class FileSaveUtilS3Impl implements IFileSaveUtil {

    @Resource
    private FileManageMapper fileManageMapper;

    @Resource
    private ObjectMapper objectMapper;

    @Value("${s3.endpoint}")
    private String endpoint;
    @Value("${s3.accesskey}")
    private String accessKey;
    @Value("${s3.secretkey}")
    private String secretKey;
    // 要上传的空间
    @Value("${s3.bucketname}")
    private String bucketName;
    @Value("${s3.region}")
    private String region;
    @Value("${s3.domain}")
    private  String domain ;

    @Value("${file.fileSaveType}")
    private  String fileSaveType;

    private S3Client client;

    @PostConstruct
    private void init(){
        // 初始化客户端

        S3ClientBuilder builder = S3Client.builder();
        builder.endpointOverride(URI.create(endpoint))
                .serviceConfiguration(S3Configuration.builder()
                        .pathStyleAccessEnabled(true) // 对于MinIO等需要启用
                        .chunkedEncodingEnabled(false) // 对于某些旧版本服务可能需要
                        .build()); // Endpoint URL
        builder.credentialsProvider(StaticCredentialsProvider.create(
                AwsBasicCredentials.create(accessKey, secretKey))); // 认证密钥
        if(region != null && !region.equals("")) {
            builder.region(Region.of(region)); // 区域
        }
        client = builder.build();
    }



    @Override
    public FileSaveResult saveFile(MultipartFile file, String subDir, String fileName) throws Exception{
        String fileKey =subDir+"/"+fileName;
        // 执行上传
        PutObjectResponse response = client.putObject(PutObjectRequest.builder()
                        .bucket(bucketName)
                        .key(fileKey)
                        .contentType(file.getContentType())
                        .contentLength(file.getSize())
                        .build(),
                RequestBody.fromBytes(file.getBytes()));
        // 拼接返回路径
        String url =  fileKey;

        FileSaveResult result = new FileSaveResult();
        result.setFileUrl(url);
        return result;
    }

    @Override
    public String getFileUrl(FileManage baseFile) throws Exception {
        String fileUrl = domain + "/" + bucketName + "/" + baseFile.getFileUrl();
        return fileUrl;
    }

    @Override
    public void deleteFile(FileManage baseFile) throws Exception {
        String fileKey = baseFile.getFileDiskPath() + "/" + baseFile.getFileName();
        client.deleteObject(DeleteObjectRequest.builder()
                .bucket(bucketName) // bucket 必须传递
                .key(fileKey) // 相对路径作为 key
                .build());
    }

    /**
     * 下载文件
     */
    public InputStream downloadFile(String fileKey, String bucketName) throws Exception {
        ResponseInputStream<GetObjectResponse> response =  client.getObject(GetObjectRequest.builder()
                .bucket(bucketName)
                .key(fileKey)
                .build());
        return response;
    }

    /**
     * 获取文件URL（带有效期）
     */
    public String getPresignedObjectUrl(String fileKey, String bucketName, int expiryMinutes) throws Exception {
        GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(fileKey)
                .build();
        try (S3Presigner presigner = S3Presigner.create()) {
            PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(
                    GetObjectPresignRequest.builder()
                            .signatureDuration(Duration.ofMinutes(expiryMinutes))
                            .getObjectRequest(getObjectRequest)
                            .build());

            return presignedRequest.url().toString();
        }
    }

}
